package com.jgdt.utils;

import cn.hutool.core.util.ObjUtil;
import cn.hutool.json.JSONObject;
import co.elastic.clients.elasticsearch._types.Refresh;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch.core.DeleteRequest;
import co.elastic.clients.elasticsearch.core.IndexRequest;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.search.Hit;
import jakarta.annotation.Resource;
import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchClient;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

import java.util.Date;
import java.util.List;
import java.util.UUID;

import static org.springframework.web.reactive.function.server.ServerResponse.ok;
import static org.springframework.web.reactive.function.server.ServerResponse.status;

/**
 * @author wangbin
 */
@Component
public class EsUtils {
    private @Resource ReactiveElasticsearchClient esClient;

    public Mono<ServerResponse> list(String indexName) {
        try {
            SearchRequest.Builder builder = new SearchRequest.Builder();
            builder.index(indexName)
                    .sort(s -> s.field(f -> f.field("createAt").order(SortOrder.Asc)))
                    .size(200);
            return esClient.search(builder.build(), JSONObject.class).flatMap(s -> {
                List<JSONObject> list = s.hits().hits().stream().map(Hit::source).toList();
                return ok().bodyValue(list);
            });
        } catch (Exception e) {
            return status(500).bodyValue(e.getMessage());
        }
    }

    public Mono<ServerResponse> save(String indexName, JSONObject bean) {
        try {
            if (ObjUtil.isEmpty(bean.getStr("id"))) {
                bean.set("id", UUID.randomUUID().toString());
                bean.set("createAt", new Date());
            } else {
                bean.set("updateAt", new Date());
            }
            IndexRequest.Builder<Object> builder = new IndexRequest.Builder<>();
            builder.index(indexName)
                    .id(bean.getStr("id"))
                    .document(bean)
                    .refresh(Refresh.True);
            return esClient.index(builder.build()).flatMap(s -> ok().bodyValue(bean));
        } catch (Exception e) {
            return status(500).bodyValue(e.getMessage());
        }
    }

    public Mono<ServerResponse> delete(String indexName, String id) {
        try {
            DeleteRequest.Builder builder = new DeleteRequest.Builder();
            builder.index(indexName)
                    .id(id)
                    .refresh(Refresh.True);
            return esClient.delete(builder.build()).flatMap(s -> Mono.empty());
        } catch (Exception e) {
            return status(500).bodyValue(e.getMessage());
        }
    }
}
